//
//  String.swift
//  BaseModule
//
//  Created by 思域 on 2020/7/21.
//

import CommonCrypto
import Foundation

public extension String {
    /// 正则密码 （最少8位，包含数字和字母）
    var validatePassword: Bool {
        let str = "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$"
        let pre = NSPredicate(format: "SELF MATCHES %@", str)
        return pre.evaluate(with: self)
    }

    /// 正则手机号
    var validateMobile: Bool {
        let str = "^((13[0-9])|(14[0-9])|(15[0-9])|(16[0-9])|(17[0-9])|(18[0-9])|(19[0-9]))\\d{8}$"
        let pre = NSPredicate(format: "SELF MATCHES %@", str)
        return pre.evaluate(with: self)
    }

    /// 正则身份证号
    var validateIdentityCard: Bool {
        let str = "^(\\d{14}|\\d{17})(\\d|[xX])$"
        let pre = NSPredicate(format: "SELF MATCHES %@", str)
        return pre.evaluate(with: self)
    }

    /// 正则email
    var validateEmail: Bool {
        let str = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
        let pre = NSPredicate(format: "SELF MATCHES %@", str)
        return pre.evaluate(with: self)
    }

    /// 计算文字所占的尺寸
    func stringSize(_ font: UIFont, boundingRect: CGSize) -> CGSize {
        let str = self as NSString
        let key: NSAttributedString.Key = .font
        let size = str.boundingRect(with: boundingRect, options: .usesLineFragmentOrigin, attributes: [key: font], context: nil)
        return size.size
    }

    /// 姓名脱敏
    /// - Returns: 2字：将姓用*代替；3字及以上：除第一和最后一位，其他用*代替
    func secretName() -> String {
        let count = self.count
        if count < 2 {
            return self
        }
        if self.count == 2 {
            let str = self as NSString
            return "*" + str.substring(from: 1)
        }

        let str = self as NSString
        return str.replacingCharacters(in: NSRange(location: 1, length: str.length - 2), with: "*")
    }

    /// 电话脱敏
    /// - Returns: 中间4位用*代替
    func secretPhone() -> String {
        if validateMobile {
            let str = self as NSString
            return str.replacingCharacters(in: NSRange(location: 3, length: 4), with: "****")
        }
        return self
    }

    /// md5加密
    func md5() -> String {
        let str = cString(using: String.Encoding.utf8)
        let strLen = CUnsignedInt(lengthOfBytes(using: String.Encoding.utf8))
        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
        let result = UnsafeMutablePointer<UInt8>.allocate(capacity: 16)
        CC_MD5(str!, strLen, result)
        let hash = NSMutableString()
        for i in 0 ..< digestLen {
            hash.appendFormat("%02x", result[i])
        }
        free(result)
        return String(format: hash as String)
    }

    /// base64解码
    func base64Decoded() -> String? {
        if let _ = range(of: ":")?.lowerBound {
            return self
        }

        let base64String = replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
        let count = base64String.count
        let m = count % 4
        let padding = count + (m == 0 ? 0 : (4 - m))
        let decodedData = Foundation.Data(base64Encoded: base64String.padding(toLength: padding, withPad: "=", startingAt: 0), options: .ignoreUnknownCharacters)
        if decodedData == nil {
            return nil
        }

        return String(data: decodedData!, encoding: .utf8)
    }
}
